from django import newforms as forms
from django.utils.translation import ugettext_lazy as _
from lp.lpx.models import Project

class ProjectForm(forms.Form):
    proname = forms.CharField(label=Project.pro_desc['proname'], max_length=26)
    objname = forms.CharField(label=Project.pro_desc['objname'], max_length=26)
    objtype = forms.CharField(label=Project.pro_desc['objtype'], widget=forms.widgets.Select(choices=Project.obj_types))
    n = forms.IntegerField(label=Project.pro_desc['n'], widget=forms.widgets.TextInput(attrs={'size': '3'}), min_value=1, max_value=20)
    m = forms.IntegerField(label=Project.pro_desc['m'], widget=forms.widgets.TextInput(attrs={'size': '3'}), min_value=0, max_value=20)
    nonzero = forms.BooleanField(label=Project.pro_desc['nonzero'], required=False)
    binary = forms.BooleanField(label=Project.pro_desc['binary'], required=False)
    integer = forms.BooleanField(label=Project.pro_desc['integer'], required=False)

    def clean_proname(self):
        _proname = self.cleaned_data['proname']
        if not _proname.replace(' ', '').isalnum():
            raise forms.ValidationError(_('Use only alphanumeric characters.'))
        return _proname

    def clean_objname(self):
        _objname = self.cleaned_data['objname']
        if not _objname.isalnum():
            raise forms.ValidationError(_('Use only alphanumeric characters.'))
        _tmp = tuple(_objname)[0]
        if not _tmp.isalpha():
            raise forms.ValidationError(_('The first character must be alphabetic.'))
        try:
            _objname.encode('ascii')
        except:
            raise forms.ValidationError(_(u'Enter a valid value.'))
        return _objname

    def save_model(self, model):
        get = self.cleaned_data.get
        for key in self.fields.keys():
            setattr(model, key, get(key))
        model.save()

class OptionsForm(forms.Form):
    _glpsol1 = (('--simplex',   _('use simplex method (default)')),
        ('--interior',  _('use interior point method (for pure LP only)')))
    _glpsol2 = (('--scale', _('scale problem (default)')),
        ('--noscale',   _('do not scale problem')))
    _simplex1 = (('--std',  _('use standard initial basis of all slacks')),
        ('--adv',   _('use advanced initial basis (default)')),
        ('--bib',   _("use Bixby's initial basis")))
    _simplex2 = (('--steep',    _('use steepest edge technique (default)')),
        ('--nosteep',   _('use standard "textbook" pricing')))
    _simplex3 = (('--relax',    _("use Harris' two-pass ratio test (default)")),
        ('--norelax',   _('use standard "textbook" ratio test')))
    _simplex4 = (('--presol',   _('use presolver (default; assumes --scale and --adv)')),
        ('--nopresol',  _('do not use presolver')))

    glpsol1 = forms.ChoiceField(label=_('Solver options 1'), choices=_glpsol1, widget=forms.widgets.RadioSelect)
    glpsol2 = forms.ChoiceField(label=_('Solver options 2'), choices=_glpsol2, widget=forms.widgets.RadioSelect)
    simplex1 = forms.ChoiceField(label=_('Simplex options 1'), choices=_simplex1, widget=forms.widgets.RadioSelect)
    simplex2 = forms.ChoiceField(label=_('Simplex options 2'), choices=_simplex2, widget=forms.widgets.RadioSelect)
    simplex3 = forms.ChoiceField(label=_('Simplex options 3'), choices=_simplex3, widget=forms.widgets.RadioSelect)
    simplex4 = forms.ChoiceField(label=_('Simplex options 4'), choices=_simplex4, widget=forms.widgets.RadioSelect)

class ProfileForm(forms.Form):
    username = forms.CharField(label=_("Username"), min_length=4, max_length=30)
    email = forms.EmailField(label=_("E-mail"))
    first_name = forms.CharField(label=_("First name"), min_length=1, max_length=30, required=False)
    last_name = forms.CharField(label=_("Last name"), min_length=1, max_length=30, required=False)

    def save_model(self, model, save=True):
        get = self.cleaned_data.get
        for key in self.fields.keys():
            print key, get(key)
            setattr(model, key, get(key))
        if save:
            model.save()

    def clean_username(self):
        _username = self.cleaned_data['username']
        if not _username.replace('_', '').isalnum():
            raise forms.ValidationError(_('You can use only alphanumeric characters and underscores.'))
        return _username

class PasswordForm(forms.Form):
    password0 = forms.CharField(label=_('Old password'), min_length=6, max_length=32, widget=forms.widgets.PasswordInput)
    password1 = forms.CharField(label=_('New password'), min_length=6, max_length=32, widget=forms.widgets.PasswordInput)
    password2 = forms.CharField(label=_('New password (again)'), min_length=6, max_length=32, widget=forms.widgets.PasswordInput)

    def __init__(self, user, *args, **kwargs):
        super(PasswordForm, self).__init__(*args, **kwargs)
        self._user = user
        if not self._user.is_active:
            del self.fields['password0']

    def clean_password0(self):
        get = self.cleaned_data.get
        if self._user.check_password(get('password0')):
            return get('password0')
        else:
            raise forms.ValidationError(_('Incorrect old password.'))

    def clean_password2(self):
        get = self.cleaned_data.get
        if (get('password1') and get('password2')) and get('password1') != get('password2'):
            raise forms.ValidationError(_('Please make sure your passwords match.'))
        if (get('password1') and get('password2')) and self._user.username == get('password2'):
            raise forms.ValidationError(_('Username and password cannot be the same.'))
        return get('password2')

    def change_password(self):
        get = self.cleaned_data.get
        self._user.set_password(get('password2'))
        self._user.is_active = True
        self._user.save()
    
class LoginForm(forms.Form):
    username = forms.CharField(label=_('Username'), max_length=30)
    password = forms.CharField(label=_('Password'), max_length=32, widget=forms.widgets.PasswordInput)

    def authenticate(self):
        from django.contrib.auth import authenticate
        get = self.cleaned_data.get
        return authenticate(username=get('username'), password=get('password'))
